home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d16 / winvn060.arc / WVFILE.C < prev    next >
Text File  |  1991-07-01  |  11KB  |  349 lines

  1. /*-- WVFILE.C -- File containing routines to do I/O under Windows.
  2.  */
  3.  
  4. #include "windows.h"
  5. #include "wvglob.h"
  6. #include "winvn.h"
  7. #ifndef MAC
  8. #include "winundoc.h"
  9. #include <io.h>
  10. #else
  11. #include <unix.h>
  12. #include <fcntl.h>
  13. #endif
  14.  
  15. #ifdef MAC
  16. extern long int _lread(HANDLE hFile, char *buf,long int bufsize);
  17. extern _llseek(HANDLE hFile,long int offset,int posmode);
  18. #endif
  19.  
  20.  
  21. /*--- function MRROpenFile --------------------------------------------
  22.  *
  23.  *  Perform the same function as Windows' OpenFile, but also
  24.  *  create an instance of a structure that keeps track of file-related
  25.  *  information (most importantly, an file buffer so I don't have to
  26.  *  do 1-byte system reads).
  27.  *
  28.  *    Entry    FileName    is the file name of the file to open.
  29.  *             vRef        is the reference number (MAC only)
  30.  *             Mode        is the mode under which to open the file.
  31.  *
  32.  *    Exit     MRRFile     points to a dynamically-allocated structure
  33.  *                         containing info about the file.
  34.  *             Returns a handle to the file; 0 if failure.
  35.  */
  36. HANDLE
  37. MRROpenFile(FileName,vRef,Mode,MRRFile)
  38. char *FileName;
  39. int vRef;
  40. int Mode;
  41. TypMRRFile **MRRFile;
  42. {
  43.    HANDLE hMyFile, hMRR;
  44.    TypMRRFile *MyMRRFile;
  45.    int retcode;
  46. #ifdef MAC
  47.    int MacMode;
  48.    int myvRef;
  49.    Str255 pFileName;
  50.    int fRefNum;
  51.    OSErr myErr;
  52. #endif
  53.  
  54.    hMRR = LocalAlloc(LMEM_FIXED,sizeof(TypMRRFile));
  55.    if(!hMRR) {
  56.       return(0);
  57.    } else {
  58.       MyMRRFile = (TypMRRFile *) LocalLock(hMRR);
  59.       MyMRRFile->hthis = hMRR;
  60.       MyMRRFile->bufidx = 0;
  61.       MyMRRFile->bytesread = 0;
  62.       MyMRRFile->eofflag = FALSE;
  63.       MyMRRFile->mode    = Mode;
  64. #ifndef MAC
  65.       if(Mode == OF_WRITE) {
  66.          hMyFile = OpenFile(FileName,&(MyMRRFile->of),OF_EXIST);
  67.          if(hMyFile == -1) Mode = OF_CREATE;
  68.       }
  69.       hMyFile = retcode = OpenFile((char far *)FileName,&(MyMRRFile->of),Mode);
  70.       if(retcode == (-1)) {
  71. #else
  72. /*
  73.       if(Mode == OF_WRITE) Mode = OF_CREATE;
  74.       if(Mode == OF_CREATE) MacMode = O_TRUNC | O_CREAT | O_RDWR;
  75.       else if(Mode == OF_WRITE) MacMode = O_APPEND | O_RDWR;
  76.       else  MacMode = O_EXCL | O_RDONLY;
  77.       MacMode |= O_TEXT;
  78. */
  79.       strcpy((char *)pFileName,FileName);
  80.       CtoPstr((char *)pFileName);
  81.       myErr = FSOpen(pFileName,vRef,&fRefNum);
  82.       MyMRRFile->vRef = vRef;
  83.       hMyFile = (HANDLE) fRefNum;
  84.       if(myErr != noErr) {
  85. #endif
  86.          LocalUnlock(hMRR);
  87.          LocalFree(hMRR);
  88.          return(0);
  89.       } else {
  90.          MyMRRFile->hFile = hMyFile;
  91.       }
  92.    }
  93.    *MRRFile = MyMRRFile;
  94.    return((HANDLE)hMyFile);
  95. }
  96.  
  97. /*--- function MRRCloseFile --------------------------------------------
  98.  *
  99.  *  Perform the same function as the close function, but also
  100.  *  deallocate the structure allocated by MRROpenFile.
  101.  *
  102.  *    Entry    MRRFile  points to a structure describing the file.
  103.  */
  104. void
  105. MRRCloseFile(MRRFile)
  106. TypMRRFile *MRRFile;
  107. {
  108.    HANDLE hMyMRRFile;
  109.    long int nbytes;
  110.  
  111.    if(MRRFile->mode == OF_WRITE || MRRFile->mode==OF_CREATE) {
  112. #ifdef MAC
  113.       nbytes = MRRFile->bufidx;
  114.       FSWrite((int)MRRFile->hFile,&nbytes,MRRFile->buf);
  115.       /* Truncate file at current file position (in case overwriting). */
  116.       GetFPos((int)MRRFile->hFile,&nbytes);
  117.       SetEOF ((int)MRRFile->hFile,nbytes);
  118. #else
  119.       write(MRRFile->hFile,MRRFile->buf,MRRFile->bufidx);
  120. #endif
  121.    }
  122. #ifdef MAC
  123.    FSClose((int)MRRFile->hFile);
  124.    FlushVol(NULL,MRRFile->vRef);
  125. #else
  126.    _lclose(MRRFile->hFile);
  127. #endif
  128.    hMyMRRFile = MRRFile->hthis;
  129.    LocalUnlock(hMyMRRFile);
  130.    LocalFree(hMyMRRFile);
  131. }
  132.  
  133. /*--- function MRRReadLine ---------------------------------------------
  134.  *
  135.  *  Read in a line from a file, very much like "fgets".
  136.  *  Lines are assumed to be terminated by CR/LF (except that this
  137.  *  is optional for the last line in a file).
  138.  *
  139.  *  No CR, LF, or zero byte is placed in the user's buffer or
  140.  *  counted as a data byte in the returned count.
  141.  *
  142.  *    Entry    MRRFile  points to a structure describing the file.
  143.  *             Linebuf  is the place to put the line.
  144.  *             Len      is the length of Linebuf.
  145.  *
  146.  *    Exit     Linebuf  contains a line.
  147.  *             Returns number of characters read.  0 means an empty line;
  148.  *              -1 means EOF.
  149.  */
  150. int
  151. MRRReadLine(MRRFile,Linebuf,Len)
  152. TypMRRFile *MRRFile;
  153. char *Linebuf;
  154. int Len;
  155. {
  156.    int BytesReturned = 0;
  157.    char ch;
  158.  
  159.    /* If we hit the EOF while reading last time, we might not have   */
  160.    /* had to return an EOF indication then--but we certainly do now. */
  161.  
  162.    if(MRRFile->eofflag) return(-1);
  163.  
  164.    /* Read bytes until we exhaust the user's buffer,                 */
  165.    /* empty our own internal buffer,                                 */
  166.    /* or hit a CR (which hopefully belongs to a CR/LF pair).         */
  167.  
  168. readlp:;
  169.    while(Len && MRRFile->bufidx < MRRFile->bytesread &&
  170.     (ch = MRRFile->buf[MRRFile->bufidx]) != '\r' && ch != '\n') {
  171.       *(Linebuf++) = ch;
  172.       BytesReturned++;
  173.       (MRRFile->bufidx)++;
  174.       Len--;
  175.    }
  176.  
  177.    /* If we emptied our own internal buffer, fill 'er up again       */
  178.    /* from the file.  If the read hits EOF, return the user's        */
  179.    /* data now (indicating EOF if we never got any data bytes        */
  180.    /* else go back up and continue taking from the buffer.           */
  181.  
  182.    if(MRRFile->bufidx >= MRRFile->bytesread) {
  183.       MRRFile->bufidx = 0;
  184.       MRRFile->bytesread = _lread(MRRFile->hFile,MRRFile->buf,BUFSIZE);
  185.       if(MRRFile->bytesread > 0) {
  186.          goto readlp;
  187.       } else {
  188.          MRRFile->eofflag = TRUE;
  189.          if(!BytesReturned) BytesReturned--;
  190.          goto endit;
  191.       }
  192.    }
  193.  
  194.    /* If we reach here, we either filled the user's buffer or        */
  195.    /* hit a CR.  No EOF was encountered.                             */
  196.    /* Either way, we must now skip to the beginning of the next      */
  197.    /* line.  This means skipping to the next LF.  Since in most      */
  198.    /* cases the user does specify a big enough buffer, in most       */
  199.    /* cases all we are doing here is reading up the next character   */
  200.    /* (assuming it's a LF).                                          */
  201.    /* All data that should go in the user's buffer is there by now.  */
  202.  
  203. skipLF:;
  204. #ifndef MAC
  205.    while(MRRFile->bufidx < MRRFile->bytesread &&
  206.      MRRFile->buf[MRRFile->bufidx] != '\n') {
  207.       (MRRFile->bufidx)++;
  208.    }
  209. #endif
  210.    /* We either found the LineFeed we were looking for, or hit       */
  211.    /* the end of our internal buffer.  If the latter, fill 'er       */
  212.    /* up and try again.                                              */
  213.  
  214.    if(MRRFile->bufidx >= MRRFile->bytesread) {
  215.       MRRFile->bufidx = 0;
  216.       MRRFile->bytesread = _lread(MRRFile->hFile,MRRFile->buf,BUFSIZE);
  217.       if(MRRFile->bytesread > 0) {
  218.          goto skipLF;
  219.       } else {
  220.          MRRFile->eofflag = TRUE;
  221.          goto endit;
  222.       }
  223.    }
  224.  
  225.    /* The buffer pointer is now pointing at the LF.  Advance         */
  226.    /* it by one so we'll get the first character of the next         */
  227.    /* line next time.                                                */
  228.    /* If this takes us past the end of the buffer, no problem.       */
  229.  
  230. #ifndef MAC
  231.    if(MRRFile->buf[MRRFile->bufidx] == '\n') (MRRFile->bufidx)++;
  232. #else
  233.    if(MRRFile->buf[MRRFile->bufidx] == '\r') (MRRFile->bufidx)++;
  234. #endif
  235.  
  236. endit:;
  237.    return(BytesReturned);
  238. }
  239.  
  240. /*--- function MRRWriteLine ---------------------------------------------
  241.  *
  242.  *  Write out a line of text, followed by a CR and LF.
  243.  *
  244.  *    Entry    MRRFile  points to a structure describing the file.
  245.  *             LineBuf  points to line buffer to write out.
  246.  *             Len      is the number of bytes to write.
  247.  */
  248. BOOL
  249. MRRWriteLine(MRRFile,LineBuf,Len)
  250. TypMRRFile *MRRFile;
  251. char far *LineBuf;
  252. int Len;
  253. {
  254.    int BytesToCopy;
  255.    static NotFirst=0;
  256.    long int nbytes;
  257. #ifdef MAC
  258.    OSErr myErr;
  259. #endif
  260.  
  261.    do {
  262.       BytesToCopy = Len < (BUFSIZE - MRRFile->bufidx) ?
  263.        Len : BUFSIZE - MRRFile->bufidx;
  264.       MoveBytes(LineBuf,(char far *)(MRRFile->buf+MRRFile->bufidx),BytesToCopy);
  265.       MRRFile->bufidx += BytesToCopy;
  266.       LineBuf += BytesToCopy;
  267.       Len -= BytesToCopy;
  268.       if(MRRFile->bufidx >= BUFSIZE) {
  269. #ifndef MAC
  270.          write(MRRFile->hFile,MRRFile->buf,BUFSIZE);
  271. #else
  272.          nbytes = BUFSIZE;
  273.          myErr = FSWrite((int) MRRFile->hFile,&nbytes,MRRFile->buf);
  274. #endif
  275.          MRRFile->bufidx = 0;
  276.       }
  277.    } while (Len > 0);
  278.  
  279.    if(!(NotFirst++)) {
  280. #ifndef MAC
  281.       MRRWriteLine(MRRFile,"\r\n",2);
  282. #else
  283.       MRRWriteLine(MRRFile,"\r\n",1);
  284. #endif
  285.    }
  286.    NotFirst--;
  287.    return(1);
  288. }
  289.  
  290. /*-- function MRRWriteDocument -----------------------------------------
  291.  *
  292.  *  Write out an entire document to disk.
  293.  *
  294.  *  Entry   Document    points to a document.
  295.  *          Offset      is the number of bytes to skip at the beginning
  296.  *                      of the line (between the end of the structure
  297.  *                      described in TypLine and the beginning of text).
  298.  *                      In most cases this will be zero.
  299.  *          szFileName  points to the file name to save to.
  300.  *          vRef        points to the directory--used only by Macintosh.
  301.  *          Append      is TRUE iff we should append to the file.
  302.  *
  303.  *    Returns TRUE iff we wrote the file OK.
  304.  */
  305. BOOL
  306. MRRWriteDocument(Document,Offset,szFileName,vRef,Append)
  307. TypDoc *Document;
  308. int Offset;
  309. char *szFileName;
  310. int vRef;
  311. BOOL Append;
  312. {
  313.    TypMRRFile  *MRRFile;
  314.    HANDLE hFile;
  315.    HANDLE hBlock;
  316.    TypBlock far *BlockPtr;
  317.    TypLine far *LinePtr;
  318.    int mode;
  319.  
  320.    if(Append) {
  321.       mode = OF_WRITE;
  322.    } else {
  323.       mode = OF_CREATE;
  324.    }
  325.    hFile = MRROpenFile(szFileName,vRef,mode,&MRRFile);
  326.    if(Append) {
  327.       _llseek(hFile, 0L, 2);
  328.    }
  329.  
  330.    if(hFile) {
  331.       LockLine(Document->hFirstBlock,sizeof(TypBlock),(TypLineID) 0L,&BlockPtr,&LinePtr);
  332.       while(LinePtr->length != END_OF_BLOCK) {
  333.          MRRWriteLine(MRRFile,((char far *)LinePtr)+Offset+sizeof(TypLine),
  334. #if 1
  335.           lstrlen(((char far *)LinePtr)+sizeof(TypLine)+Offset) );
  336. #else
  337.           LinePtr->length-sizeof(TypLine)-sizeof(int)-1);
  338. #endif
  339.          NextLine(&BlockPtr,&LinePtr);
  340.       }
  341.       GlobalUnlock(BlockPtr->hCurBlock);
  342.       MRRCloseFile(MRRFile);
  343.    } else {
  344.       return(0);
  345.    }
  346.    return(TRUE);
  347. }
  348. 
  349.